/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ucmconfchecker.ucmrender;

import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.Graph;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.geom.Point2D;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.collections15.Transformer;
import ucmconfchecker.conformance.Edge;
import ucmconfchecker.conformance.Scenario;
import ucmconfchecker.pArchitecture.Component;
import ucmconfchecker.pArchitecture.Responsibility;

/**
 *
 * @author Alex
 */
public class UCMFlabotLayout implements Layout<Responsibility,Edge>{

    private Scenario<Responsibility> g;
    
    private Map<Responsibility, Point2D> responsibilityPosition = new HashMap<Responsibility, Point2D>();
    private Map<Responsibility, Boolean> responsibilityLocked = new HashMap<Responsibility, Boolean>();
    private Map<Component, Point2D> componentPosition = new HashMap<Component, Point2D>();
    private Map<Component, Dimension> componentDimension = new HashMap<Component, Dimension>();
    private Dimension size = new Dimension(500,500);
    
    public UCMFlabotLayout(){

    }
    public void initialize() {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public void setInitializer(Transformer<Responsibility, Point2D> t) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public void setGraph(Graph<Responsibility, Edge> graph) {
        this.g = (Scenario<Responsibility>)graph;
    }

    public Graph<Responsibility, Edge> getGraph() {
        return g;
    }

    public void reset() {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public void setSize(Dimension dmnsn) {
        this.size = dmnsn;
    }

    public Dimension getSize() {
       return size;
    }

    public void lock(Responsibility v, boolean bln) {
        //nothing, its already locked
    }

    public boolean isLocked(Responsibility v) {
        Boolean locked = responsibilityLocked.get(v);
        if(locked!=null && !locked){
            return false;
        }else{
            return true;
        }
    }

    public void setLocation(Responsibility v, Point2D pd) {
        Point2D componentPosition = getPosition(v.getComponent());
        Dimension componentDimension = getDimensions(v.getComponent()); 
        int minX = (int) componentPosition.getX();
        int maxX = (int) (componentPosition.getX()+ componentDimension.getWidth());
        int minY = (int) componentPosition.getY();
        int maxY = (int) (componentPosition.getY()+ componentDimension.getHeight());
        if(pd.getX()<minX || pd.getX()>maxX || pd.getY()<minY || pd.getY()>maxY){
          //nothing
        }else{
            responsibilityPosition.put(v, pd);
        }
    }
    public void setLocation(Component c, Point2D pd) {
        componentPosition.put(c, pd);
    }
    public Point2D transform(Responsibility i) {
        Point2D responsibilityPos = responsibilityPosition.get(i);
        if(responsibilityPos!=null){
//            Point2D componentPos = componentPosition.get(i.getComponent());
//            if(componentPos!=null){
//                return new Point((int)(responsibilityPos.getX()+componentPos.getX()),
//                                 (int)(responsibilityPos.getY()+componentPos.getY()));
//            }else{
                return responsibilityPos;
//            }
        }else{
            return new Point(0,0);
        }
    }

    public void setDimensions(Component component, Dimension size) {
        componentDimension.put(component, size);
    }
    public Dimension getDimensions(Component component){
        return componentDimension.get(component);
    }

    public Collection<Component> getComponents() {
        return componentDimension.keySet();
    }

    public Point2D getPosition(Component component) {
        return componentPosition.get(component);
    }
}
